#include "protocol.h" 

#include <QDebug>

Protocol::Protocol(void)
{
    clearProtocoldata();
}

Protocol::~Protocol(void){}

QByteArray Protocol::packetMsg(quint8 device, quint8 deviceCmd,
                               quint8 dataLen, quint8 *data)
{  
    m_device        = device;
    m_deviceCmd 	= deviceCmd;
    m_dataLen 		= dataLen;
    m_data 			= data;

    QByteArray array;
    array.append(m_sendBegin);
    array.append(m_device);
    array.append(m_deviceCmd);
    array.append(m_dataLen);

    if(m_dataLen > 0)
    {
        for(int i = 0; i < m_dataLen; i++)
        {
            array.append(m_data[i]);
        }
    }else
    {
        array.append('\0');
    }

    array.append(m_sendEnd);
    array.append(gainCheckSum());
    return array;
}

void Protocol::clearProtocoldata(void)
{
    m_sendBegin        = BGN_RESD_MSG;
    m_device           = PROT_FULL_CMD;
    m_deviceCmd        = PROT_FULL_CMD;
    m_dataLen          = PROT_ZERO_LEN;
    m_data             = PROT_FULL_DATA;
    m_sendEnd          = END_RESD_MSG;
    m_checkSum         = PROT_FULL_CRC;
}

quint8 Protocol::gainCheckSum(void)
{
    quint8 checkSum = 0;
    calcuCheckChar(m_sendBegin, checkSum);
    calcuCheckChar(m_device, checkSum);
    calcuCheckChar(m_deviceCmd, checkSum);
    calcuCheckChar(m_dataLen, checkSum);
    if(m_dataLen > 0)
    {
        for(int i = 0; i < m_dataLen; i++)
        {
            calcuCheckChar(m_data[i], checkSum);
        }
    }else
    {
        calcuCheckChar('\0', checkSum);
    }
    calcuCheckChar(m_sendEnd, checkSum);
    return checkSum;
}

quint8 Protocol::calcuCheckChar(quint8 data, quint8 &crc)
{
    int i = 0;
    quint8 crc_poly = 0x07;
    crc ^= data;

    for(i = 0; i < 8; i++)
    {
        if(crc & 0x80)
        {
            crc <<= 1;
            crc ^= crc_poly;
        }else
        {
            crc <<= 1;
        }
    }
    return (crc & 0xFF);
}

void Protocol::printProtocoldata(void)
{
    qDebug() << "起始标志: " << m_sendBegin;      //起始标志 	以“{”开始
    qDebug() << "设备模块: " << m_device;         //模块命令   	以大写字母 A~Z 为命令
    qDebug() << "模块命令: " << m_deviceCmd;
    qDebug() << "数据长度: " << m_dataLen;        //数据长度   	没有为0
    for(int i = 0; i < m_dataLen; i++)
    {
        qDebug() << "数据内容: " << m_data[i];    //数据		没有指向空
    }

    qDebug() << "奇偶校验: " << m_checkSum;
    qDebug() << "结束标志: " << m_sendEnd;        //结束标志	以“}”结束
}
